package com.deepface.common.utils.process;

import com.deepface.common.config.DflConfig;
import com.deepface.common.exception.UtilException;
import com.sun.jna.Pointer;
import com.sun.jna.platform.win32.Kernel32;
import com.sun.jna.platform.win32.WinNT;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.lang.reflect.Field;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @ClassName ProcessUtils
 * @Description java执行本地进程工具类
 * @Author 74707
 * @Date 2023/12/8 19:43
 * @Version V1.0
 */
public class ProcessUtils {

  private static final Logger log = LoggerFactory.getLogger(ProcessUtils.class);

  // 执行命令
  public static Process start(String... command)  {
    System.out.println(command);
    try {
      // 新建ProcessBuilder
      ProcessBuilder processBuilder = new ProcessBuilder(command);
      // 切换工作目录
      processBuilder.directory(new File(DflConfig.getRootWorkPath()));

      System.out.println("DflConfig.getRootWorkPath()");
      System.out.println(DflConfig.getRootWorkPath());

      Process process = processBuilder.start();
      processBuilder.redirectErrorStream(true);

      return process;
    }catch (IOException e){
      e.printStackTrace();
      throw new UtilException("Process命令执行失败");
    }

  }

  // 获取父进程pid
  private static long getParentPid(Process process){
    long pid = 0;
    try {
      if(process.getClass().getName().equals("java.lang.Win32Process") ||
          process.getClass().getName().equals("java.lang.ProcessImpl") ){
        // 获取windows下的pid
        Field field = process.getClass().getDeclaredField("handle");
        field.setAccessible(true);
        long handl = field.getLong(process);
        Kernel32 kernel = Kernel32.INSTANCE;
        WinNT.HANDLE handle = new WinNT.HANDLE();
        handle.setPointer(Pointer.createConstant(handl));
        pid = kernel.GetProcessId(handle);
      }
      System.out.println("parent pid:"+pid);
      return pid;
    }catch (Exception e){
      throw new UtilException("父进程pid已消失");
    }
  }

  // 获取子进程pid
  public static Long getPid(Process process) {
    try {
      // window根据父进程查询子进程id
      String cmd = "wmic process where (ParentProcessId=" + getParentPid(process) + ") get ProcessId";
      Process wmicProcess = Runtime.getRuntime().exec(cmd);
      try (BufferedReader reader = new BufferedReader(new InputStreamReader(wmicProcess.getInputStream()))) {
        String lastline="";
        String line;
        while ((line = reader.readLine()) != null) {
          System.out.println("line:"+line);
          if(line.length()!=0){
            lastline = line;
          }
        }
        // 只获取最后一行的pid
        System.out.println("lastline:"+lastline);
        long processId = Integer.parseInt(lastline.trim());
        return processId;
      }
    } catch (IOException e) {
      throw new UtilException("子进程pid已消失");
    }
  }

  // 停止进程
  public static void stop(long pid){
    String cmd = "taskkill /PID " + pid +" /F";
    System.out.println(cmd);
    try {
      Runtime.getRuntime().exec(cmd);
    }catch (IOException e){
      throw new UtilException("cmd执行阻塞");
    }
  }

  // 读取设备信息
  public static void readMessage(Process process){
    String line = "";
    try {
      BufferedReader in=new BufferedReader(new InputStreamReader(process.getInputStream()));
      while((line= in.readLine())!=null){
        System.out.println(line);
      }
    }catch (Exception e){
      throw new UtilException("缓冲区错误");
    }
  }

}
